module UART_Controller(
	//Host side
	iCLK,									//50 MHz
	iStartTransmit,					//Start sending
	iStartAddress,						//Start address
	iEndAddress,						//End address
	oBusy,								//UART controller busy
	//UART transmitter side
	oTXD,
	//MEmory side
	oMEM_ADDR,
	iMEM_DATA,
	oMEM_CLK
);

input iCLK,iStartTransmit;
input [17:0] iStartAddress;
input [17:0] iEndAddress;
output reg oBusy;
output oTXD;

reg [7:0] oUART_DATA;
reg oUART_START;
wire iUART_BUSY;

output reg [17:0] oMEM_ADDR;
input [7:0] iMEM_DATA;
output reg oMEM_CLK;

reg prev_iStartTransmit;
reg uart_started;
reg [2:0] state;
reg [17:0] end_addr;
always@(posedge iCLK)
begin
	prev_iStartTransmit <= iStartTransmit;
	
	if(({prev_iStartTransmit,iStartTransmit} == 2'b01) && !uart_started) begin
		uart_started <= 1;		
		oMEM_ADDR <= iStartAddress;
		end_addr <= iEndAddress;
		state <= 3'b000;
		oMEM_CLK <= 0;
		oBusy <= 1;
	end
	
	if(uart_started) begin
		
		case(state)
			//Set memory address
			3'b000: begin
				oMEM_CLK <= 1;
				state <= 3'b001;				
			end
			//Reading Uart data
			3'b001: begin
				oMEM_CLK <= 0;
				oUART_DATA <= iMEM_DATA;
				state <= 3'b010;
			end
			//Uart sending start
			3'b010: begin
				//UART_TXD_DATA <= CIRCLE_BUFF_Q[7:0];
				oUART_START <= 1;
				state <= 3'b011;
			end
			//Set start to low
			3'b011: begin
				oUART_START <= 0;
				//uclock <= 0;
				state <= 3'b100;
			end
			//Wait till finished sending
			3'b100: begin
				if(!iUART_BUSY) begin
					state <= 3'b101;
				end
			end
			//Set next memory address
			3'b101: begin
				oMEM_ADDR <= oMEM_ADDR + 1'b1;
				state <= 3'b000;
				if(oMEM_ADDR == end_addr) begin
					uart_started <= 0;
					oBusy <= 0;
				end
			end
		endcase
	end
end

async_transmitter trans(
	.clk(~iCLK), 
	.TxD_start(oUART_START), 
	.TxD_data(oUART_DATA), 
	.TxD(oTXD), 
	.TxD_busy(iUART_BUSY)
	);

endmodule
